<template>
  <h1 class="text-xl">CompositionEvent</h1>
  <p class="text-base">
    用户在通过输入法输入需要组合生成的文字时（如中文），会触发
    <a
      class="text-blue-400"
      target="_blank"
      href="https://developer.mozilla.org/zh-CN/docs/Web/API/CompositionEvent"
    >
      CompositionEvent 类型事件</a
    >， 这个事件接口有3个事件， compositionstart, compositionupdate 和 compositionend，
    以中文输入法为例， 在输入中文时，输入法弹出时会触发 compositionstart，
    每按一次键盘（或者说组成一个字，这要看输入法）会触发 compositionupdate，
    文字从输入法进入页面会触发 compositionend。
  </p>
  <hr />
  <br />
  <p class="text-xl">
    <a
      class="text-blue-400"
      href="https://developer.mozilla.org/zh-CN/docs/Web/API/Document/execCommand"
      target="_blank"
    >
      document.execCommand</a
    >
  </p>
  <p class="text-base">
    这个方法已经废弃了，但还是有必要说明一下，如果需要改变html文档内容，这里可以作为参考。
  </p>
  <p class="text-base">
    当一个 HTML 文档切换到设计模式时，document暴露 execCommand
    方法，该方法允许运行命令来操纵可编辑内容区域的元素。
  </p>
  <p class="text-base">
    使用 document.execCommand('insertText', false, char);
    在光标插入位置插入文本内容或者覆盖所选的文本内容。
  </p>
  <hr />
  <br />
  <pre class="max-h-52 overflow-auto">
function simulateIMEInput(text) {
    // Focus on the current active element
    const activeElement = document.activeElement;

    if (!activeElement) {
        console.error('No active element to receive input.');
        return;
    }

    // Start composition
    let event = new CompositionEvent('compositionstart', {
        bubbles: true,
        cancelable: true,
        data: ''
    });
    activeElement.dispatchEvent(event);

    // Input each character
    for (let i = 0; i < text.length; i++) {
        const char = text[i];

        // Simulate composition update
        event = new CompositionEvent('compositionupdate', {
            bubbles: true,
            cancelable: true,
            data: text.substring(0, i + 1)
        });
        activeElement.dispatchEvent(event);

        // Insert the character using execCommand
        document.execCommand('insertText', false, char);
    }

    // End composition
    event = new CompositionEvent('compositionend', {
        bubbles: true,
        cancelable: true,
        data: text
    });
    activeElement.dispatchEvent(event);

    // Final input event
    event = new InputEvent('input', {
        inputType: 'insertText',
        data: text,
        bubbles: true,
        cancelable: true
    });
    activeElement.dispatchEvent(event);
}
  </pre>
  <hr />
  <br />

  <div>
    <Button label="测试" @click="test"/>
    <Button label="测试2" @click="test2"/>
    <br>
    <br>
    <InputText type="text" v-model="vv" />
    <br>
    <br>
    <InputText type="text" ref="other" @change="otherChangeEvent" @input="otherInputEvent" />
    <br>
    <br>
    <div class="bg-slate-300 rounded-sm border-blue-200" contenteditable="true" ref="otherDiv"></div>
  </div>
</template>
<script setup lang="ts">
import { ref, useTemplateRef } from 'vue'

const vv = ref('')
const otherRef = useTemplateRef('other')
const otherDivRef = useTemplateRef('otherDiv')

function test() {
  console.log(otherRef.value)
  simulateIMEInput(vv.value)
}
function test2() {
  setTimeout(() => {
    otherDivRef.value?.focus()
    simulateIMEInput(vv.value)
  },100)
}


function otherChangeEvent(e: any) {
  console.log('input', e)
}
function otherInputEvent(e: any) {
  console.log('change', e)
}
function simulateIMEInput(text: string) {
  // Focus on the current active element
  const activeElement = document.activeElement

  if (!activeElement) {
    console.error('No active element to receive input.')
    return
  }

  // Start composition
  let event = new CompositionEvent('compositionstart', {
    bubbles: true,
    cancelable: true,
    data: '',
  })
  activeElement.dispatchEvent(event)

  // Input each character
  for (let i = 0; i < text.length; i++) {
    const char = text[i]

    // Simulate composition update
    event = new CompositionEvent('compositionupdate', {
      bubbles: true,
      cancelable: true,
      data: text.substring(0, i + 1),
    })
    activeElement.dispatchEvent(event)

    // Insert the character using execCommand
    document.execCommand('insertText', false, char)
  }

  // End composition
  event = new CompositionEvent('compositionend', {
    bubbles: true,
    cancelable: true,
    data: text,
  })
  activeElement.dispatchEvent(event)

  // Final input event
  const inputEvent = new InputEvent('input', {
    inputType: 'insertText',
    data: text,
    bubbles: true,
    cancelable: true,
  })
  activeElement.dispatchEvent(inputEvent)
}
</script>

<style scoped></style>
